package com.tangsm.spring.boot.async;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * spring boot异步多线程实例启动类
 *
 * <p>@Async配置自定义线程池方式</p>
 * <pre>
 * 自定义线程池，可对系统中线程池更加细粒度的控制，方便调整线程池大小配置，线程执行异常控制和处理。
 * 在设置系统自定义线程池代替默认线程池时，虽可通过多种模式设置，但替换默认线程池最终产生的线程池有且只能设置一个（不能设置多个类继承AsyncConfigurer）。
 * 自定义线程池有如下模式：
 *   1. 重新实现接口AsyncConfigurer
 *   2. 继承AsyncConfigurerSupport
 *   3. 配置由自定义的TaskExecutor替代内置的任务执行器，@Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME)。
 * 注：以上三种方式只能存在一种，不然会启动报错：Only one AsyncConfigurer may exist。
 *
 * Spring中用@Async注解标记的方法，称为异步方法。在spring boot应用中使用@Async很简单：
 *   1. @Configuration线程池任务执行器配置类上或者启动类加上注解@EnableAsync
 *   2. 在需要被异步调用的方法外加上@Async
 *   3. 所使用的@Async注解方法的类对象应该是Spring容器管理的bean对象；
 * 如下方式会使@Async失效：
 *   1. 异步方法使用static修饰
 *   2. 异步类没有使用@Component注解（或其他注解）导致spring无法扫描到异步类
 *   3. 异步调用不能与异步方法在同一个类中
 *   4. 类中需要使用@Autowired或@Resource等注解自动注入，不能自己手动new对象
 *   5. 如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解或者配置类开启@EnableAsync
 *   6. 在Async 方法上标注@Transactional是没用的。 在Async 方法调用的方法上标注@Transactional 有效。
 * </pre>
 *
 * @see <a href="https://note.youdao.com/s/YhZp2YqS">@Async异步注解实战</a>
 * @author tangsm
 */
@SpringBootApplication
public class AsyncApplication {
    public static void main(String[] args) {
        SpringApplication.run(AsyncApplication.class, args);
    }
}
